package cc.rengu.igas.share.core.service.trans;


import cc.rengu.igas.share.common.constant.TransCacheConstant;
import cc.rengu.igas.share.common.enums.FeeTypeEnum;
import cc.rengu.igas.share.common.enums.RespCodeEnum;
import cc.rengu.igas.share.core.realize.MchntService;
import cc.rengu.igas.share.core.realize.impl.MchntServiceImpl;
import cc.rengu.igas.share.core.service.base.NoticeService;
import cc.rengu.igas.share.facade.bean.TradeFundBillBean;
import cc.rengu.igas.share.facade.request.AlipayPayResultNoticeRequest;
import cc.rengu.igas.share.facade.response.AlipayPayResultNoticeResponse;
import cc.rengu.oltp.service.base.ChannelBaseService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.entity.ChannelCallCfg;
import cc.rengu.oltp.service.common.entity.MchntOrderInfo;
import cc.rengu.oltp.service.common.entity.PayOrderInfo;
import cc.rengu.oltp.service.common.entity.UserOrderInfo;
import cc.rengu.oltp.service.common.enums.*;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.model.OrderInfo;
import cc.rengu.oltp.service.realize.OrderService;
import cc.rengu.oltp.service.realize.TransCustomImpl;
import cc.rengu.oltp.service.realize.impl.OrderServiceImpl;
import cc.rengu.oltp.utility.util.*;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * Create by wangcheng on 2021-09-30
 * 支付宝异步通知处理服务
 */
public class AlipayPayResultNoticeService extends NoticeService implements TransCustomImpl {

    @Override
    protected Object bizBeforeCust() throws Exception {
        AlipayPayResultNoticeRequest alipayPayResultNoticeRequest = new AlipayPayResultNoticeRequest();
        ConvertUtil.convertOutput(alipayPayResultNoticeRequest);
        return alipayPayResultNoticeRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        AlipayPayResultNoticeRequest alipayPayResultNoticeRequest = (AlipayPayResultNoticeRequest) request;
        AlipayPayResultNoticeResponse alipayPayResultNoticeResponse = new AlipayPayResultNoticeResponse();
        alipayPayResultNoticeResponse.setHeader(alipayPayResultNoticeRequest.getHeader());
        BizResponse bizResponse = new BizResponse();
        String instId = alipayPayResultNoticeRequest.getHeader().getInstId();
        String orderId = alipayPayResultNoticeRequest.getOrderId();

        /* 获取通知交易的原交易订单信息 */
        OrderService orderService = new OrderServiceImpl();
        OrderInfo orderInfo = orderService.selectOrderInfoBySysSeqNum(instId, orderId);
        if (null == orderInfo) {
            rglog.error("机构<{}>没有对应的银联订单号<{}>信息", instId, orderId);
            throw new BizException(RespCodeEnum.ORDER_NOT_EXIST.getRespCode(), RespCodeEnum.ORDER_NOT_EXIST.getRespDesc());
        }
        UserOrderInfo userOrderInfo = orderInfo.getUserOrderInfo();
        List<MchntOrderInfo> mchntOrderInfoList = orderInfo.getMchntOrderInfoList();
        if (mchntOrderInfoList.size() > 1) {
            rglog.error("支付宝支付不支持合并订单支付");
            throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
        }
        List<PayOrderInfo> payOrderInfoList = orderInfo.getPayOrderInfoList();
        Optional<PayOrderInfo> payOrderInfoOpt = payOrderInfoList.stream().filter(item -> item.getMsgDstId().equals(ChannelEnum.UPWX.getChannelType()) ||
                item.getMsgDstId().equals(ChannelEnum.NUWX.getChannelType()) || item.getMsgDstId().equals(ChannelEnum.WXZF.getChannelType())).findFirst();
        if (!payOrderInfoOpt.isPresent()) {
            rglog.error("机构<{}>没有对应的银联订单号<{}>信息", instId, orderId);
            throw new BizException(RespCodeEnum.ORDER_NOT_EXIST.getRespCode(), RespCodeEnum.ORDER_NOT_EXIST.getRespDesc());
        }
        PayOrderInfo payOrderInfo = payOrderInfoList.get(0);
        if (TransStatusEnum.TRANS_SUCC.getStatus().equals(payOrderInfo.getTransStatus()) &&
                (BizStatusEnum.FINISH.getStatus().equals(payOrderInfo.getBizStatus()) ||
                        BizStatusEnum.REFUND.getStatus().equals(payOrderInfo.getBizStatus()) ||
                        BizStatusEnum.PART_REFUND.getStatus().equals(payOrderInfo.getBizStatus()) ||
                        BizStatusEnum.CONFIRM.getStatus().equals(payOrderInfo.getBizStatus()))) {
            rglog.debug("订单已成功，不处理直接返回结果");
            alipayPayResultNoticeResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
            alipayPayResultNoticeResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
            bizResponse.setResult(alipayPayResultNoticeResponse);
            bizResponse.setRspSysId(AppParamConstant.IGAS);
            bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
            bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
            return bizResponse;
        }

        /* 支付成功,更新当前支付订单状态 */
        userOrderInfo.setOrderStatus(OrderStatusEnum.FINISH.getStatus());
        userOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
        userOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
        userOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        for (MchntOrderInfo mchntOrderInfo : mchntOrderInfoList) {
            mchntOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
            mchntOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
            mchntOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        }
        payOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
        payOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
        payOrderInfo.setSettleDate(DateUtil.getCurrentDate());
        payOrderInfo.setChannelOrderId(alipayPayResultNoticeRequest.getChannelOrderId());
        payOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        /* 相应码和相应码 */
        payOrderInfo.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        payOrderInfo.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        /* 付款方账户信息处理 */
        payOrderInfo.setPayerAcctType(AcctTypeEnum.ALL.getAcctType());
        List<TradeFundBillBean> tradeFundBillList = alipayPayResultNoticeRequest.getTradeFundBillList();
        if (null != tradeFundBillList && !tradeFundBillList.isEmpty()) {
            /* CREDIT_CARD:信用卡 MIXED_CARD:借贷合一卡 */
            TradeFundBillBean tradeFundBill = tradeFundBillList.get(0);
            String payerAcctType = "DEBIT_CARD".equals(tradeFundBill.getFundType()) ? AcctTypeEnum.OTHER_DEBIT.getAcctType() : AcctTypeEnum.OTHER_CREDIT.getAcctType();
            payOrderInfo.setPayerAcctType(payerAcctType);
        }
        /* 付款信息 */
        payOrderInfo.setPayerAcctInfo(alipayPayResultNoticeRequest.getBuyerLogonId());
        /* 判断是否有商户在支付宝侧的营销,商户出资优惠金额=订单金额-商户实收金额 */
        if (!StringUtil.isEmptyOrNull(alipayPayResultNoticeRequest.getPayAmt()) &&
                !StringUtil.isEmptyOrNull(alipayPayResultNoticeRequest.getReceiptAmt())
                && AmountUtil.compare(alipayPayResultNoticeRequest.getPayAmt(), alipayPayResultNoticeRequest.getReceiptAmt()) > 0) {
            /* 支付宝订单金额=用户实际支付金额>支付宝商户清算金额，存在支付宝营销 */
            rglog.debug("存在商户侧，在支付宝侧出资优惠金额<{}>", AmountUtil.subtraction(alipayPayResultNoticeRequest.getPayAmt(), alipayPayResultNoticeRequest.getReceiptAmt()));
            /* 处理营销金额,更新用户优惠金额累计，实际优惠金额=实际优惠金额 +支付宝优惠金额 */
            userOrderInfo.setRealDiscountAmt(AmountUtil.addition(userOrderInfo.getRealDiscountAmt(),
                    AmountUtil.subtraction(alipayPayResultNoticeRequest.getPayAmt(), alipayPayResultNoticeRequest.getReceiptAmt())));
            /* 用户订单表的实际支付金额=用户订单表的实际支付金额-支付宝优惠金额 */
            userOrderInfo.setRealPayAmt(AmountUtil.subtraction(userOrderInfo.getRealPayAmt(),
                    AmountUtil.subtraction(alipayPayResultNoticeRequest.getPayAmt(), alipayPayResultNoticeRequest.getReceiptAmt())));
            /* 处理商户清算金额 商户订单表中实际清算金额=实际清算金额-支付宝优惠金额 */
            for (MchntOrderInfo mchntOrderInfo : mchntOrderInfoList) {
                mchntOrderInfo.setRealSettleAmt(AmountUtil.subtraction(mchntOrderInfo.getRealSettleAmt(),
                        AmountUtil.subtraction(alipayPayResultNoticeRequest.getPayAmt(), alipayPayResultNoticeRequest.getReceiptAmt())));
            }
            /* 存储通道优惠金额 */
            payOrderInfo.setChannelDiscountAmt(AmountUtil.subtraction(alipayPayResultNoticeRequest.getPayAmt(), alipayPayResultNoticeRequest.getReceiptAmt()));
            /* 支付订单表的实际支付金额=支付订单表的实际支付金额-支付宝优惠金额 */
            payOrderInfo.setRealPayAmt(AmountUtil.subtraction(payOrderInfo.getRealPayAmt(),
                    AmountUtil.subtraction(alipayPayResultNoticeRequest.getPayAmt(), alipayPayResultNoticeRequest.getReceiptAmt())));

        } else {
            /*默认支付侧无商户营销，金额做处理*/
            rglog.debug("支付宝订单金额:<{}>,支付宝商户打款金额:<{}>", alipayPayResultNoticeRequest.getPayAmt(), alipayPayResultNoticeRequest.getReceiptAmt());
        }

        /* 计算商户手续费 */
        GlobalTransUtil.setCacheValue(TransCacheConstant.MCHNT_ORDER_INFO_LIST, mchntOrderInfoList);
        MchntService mchntService = new MchntServiceImpl();
        boolean calcResult = mchntService.calcMchntFee(mchntOrderInfoList, FeeTypeEnum.WECHAT.getFeeType());
        if (!calcResult) {
            rglog.debug("商户手续费计算失败，只更新订单状态！");
            orderService.updateOrderInfo(userOrderInfo, mchntOrderInfoList, payOrderInfo);
        } else {
            /* 计算商户优惠手续费以、虚拟账户记账以及交易通知等 */
            if (null == txnInfo.getChannelCallCfgList() || txnInfo.getChannelCallCfgList().isEmpty()) {
                rglog.error("<{}-{}>交易未配置交易通道服务调用配置信息！", txnInfo.getSrcTxnAuthCfg().getTxnNum(), txnInfo.getSrcTxnAuthCfg().getTxnName());
                throw new BizException(RespCodeEnum.TRANS_NOT_SUPPORT.getRespCode(), RespCodeEnum.TRANS_NOT_SUPPORT.getRespDesc());
            }
            List<ChannelCallCfg> channelCallCfgList = txnInfo.getChannelCallCfgList().stream().filter(item ->
                    item.getCallIndex().equals(ChannelBaseService.FIRST_CHANNEL_CALL_INDEX)).collect(Collectors.toList());
            ChannelCallCfg channelCallCfg = channelCallSceneDiscern(alipayPayResultNoticeRequest, channelCallCfgList);
            Class channelClasz = Class.forName(channelCallCfg.getCallChannelImpl());
            ChannelBaseService channelBaseService = (ChannelBaseService) channelClasz.newInstance();
            channelBaseService.callService(txnInfo, orderInfo, channelCallCfg.getBizScene(), request);
        }

        /* 更新商户累计限额 */
        mchntService.updateMchntTransLimit(mchntOrderInfoList);

        /* 组装应答报文 */
        alipayPayResultNoticeResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        alipayPayResultNoticeResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(alipayPayResultNoticeResponse);
        bizResponse.setRspSysId(AppParamConstant.IGAS);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        AlipayPayResultNoticeResponse alipayPayResultNoticeResponse = (AlipayPayResultNoticeResponse) bizResponse.getResult();
        ConvertUtil.convertInput(alipayPayResultNoticeResponse);
    }

    @Override
    public ChannelCallCfg channelCallSceneDiscern(Object request, List<ChannelCallCfg> channelCallCfgList) throws Exception {
        return null;
    }

    @Override
    public CheckResultEnum channelCallPreCheck(Object request, ChannelCallCfg channelCallCfg, OrderInfo orderInfo) throws Exception {
        return null;
    }

    @Override
    public TransStatusEnum channelCallResultProc(Object request, ChannelCallCfg channelCallCfg, TransStatusEnum transStatusEnum, Object channelResponse, OrderInfo needUpdateOrderInfo) throws Exception {
        return null;
    }
}
